<script setup>
import { reactive, ref, watch, onMounted, onBeforeUnmount } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import { loadBMapGLScript, getMaskOverlay } from '@T2/utils/BMapGL_API.ts';
import { warnApi, unitById } from '@T2/service/api.ts';
import { getUnitsParams } from '@T2/utils/params.ts';
import { mapStyle } from './mapStyle.js';
import { useIuserInfoStore } from '@T2/store/users.ts';
import NormalPNG from '@T2/assets/maps/buoy-normal.png';
import dayjs from 'dayjs';
import Units from './framework/units.vue';

const iuserInfoStore = useIuserInfoStore();
const { info } = iuserInfoStore;

const clickHandlers = [];
let maps = {};
const Rt = reactive({
  units: undefined,
  sensors: [],
});
onMounted(async () => {
  if (!window.BMapGL) {
    await loadBMapGLScript();
  }
  const { unitList, curIds } = await getUnitsParams('/P/Manage/map01');
  Rt.units = unitList.filter(i => +i.x && +i.y);
  const warnList = await getWarnList();
  curIds.forEach(j => {
    const obj = warnList.find(i => i.sensor === j.s);
    j.state = obj ? false : true;
  });
  const flag = true;
  // const flag = import.meta.env.MODE !== 'development';
  flag && mapsInit();
})
const getWarnList = () => {
  return new Promise((resolve, reject) => {
    warnApi({
      method: 'get',
      params: {
        page: 1,
        reset_time__isnull: true,
      }
    }).then(res => {
      resolve(res.results || []);
    }).catch(res => {
      reject([]);
    });
  });
}
const mapsInit = () => {
  if (!Rt.units.length) {
    ElMessage.error('未查询到设置了经纬度的站点！');
    return;
  }
  maps = new window.BMapGL.Map('map_container', { minZoom: 10 });
  maps.setMapStyleV2({styleJson: mapStyle});
  maps.setTilt(0);    // 设置地图倾斜角
  maps.setHeading(0); // 设置地图倾斜角
  maps.enableKeyboard();
  maps.enableScrollWheelZoom();
  maps.enableInertialDragging();
  maps.enableContinuousZoom();
  maps.setDisplayOptions({ poi: true, poiIcon: false});
  getMaskOverlay('上海市', 1).then(res => {
    res?.mapmasks?.forEach(i => maps.addOverlay(i));
    res?.borders?.forEach(i => maps.addOverlay(i));
  });
  
  /* viewPort: { center: {lat: 31.13, lng: 121.1}, zoom: 12 } */
  
  const points = Rt.units.map(i => new window.BMapGL.Point(+i.x, +i.y));
  const viewPort = maps.getViewport(points);
  maps.centerAndZoom(viewPort.center, viewPort.zoom > 12 ? 12 : viewPort.zoom);
  
  initHome(maps.getCenter(), maps.getZoom());
  
  const icon = new window.BMapGL.Icon(NormalPNG, new window.BMapGL.Size(0, 0));
  Rt.units.forEach(item => {
    const clickHandler = function(e) {
      openInfoWindow(item);
    };
    let marker = new window.BMapGL.Marker(new window.BMapGL.Point(+item.x, +item.y), { icon: icon });
    maps.addOverlay(drawMarker(marker, item));
    marker.addEventListener('click', clickHandler);
    clickHandlers.push({ marker, clickHandler });
  });
}
onBeforeUnmount(() => {
  clickHandlers.forEach(({ marker, clickHandler }) => {
    marker.removeEventListener('click', clickHandler);
  });
});
const drawMarker = (marker, item) => {
  setTimeout(() => {
    let eleIcon = document.createElement('div');
    eleIcon.className = item.warn_number > 0 ? 'map-buoy alarm' : 'map-buoy';
    marker.domElement.appendChild(eleIcon);
  }, 100);
  return marker;
}

/* 点击marker弹窗 */
const detail = reactive({
  data: null,
  dom: null,
});
const openInfoWindow = (item) => {
  const point = new window.BMapGL.Point(+item.x, +item.y);
  const content = `<div class="openTips" id="tipsUnitID${ item.id }"></div>`;
  const infoWindow = new window.BMapGL.InfoWindow(content, {
    width: 0,
    offset: new window.BMapGL.Size(-29, 0), //默认的一个引导箭头,宽58px,高31px,往左偏移一半宽度
  });
  maps.openInfoWindow(infoWindow, point);
  setTimeout(() => {
    detail.dom = document.getElementById(`tipsUnitID${ item.id }`);
  }, 50);
  detail.data = item;
}
const closeInfoWindow = () => {
  maps.closeInfoWindow();
}

/* 回到初始地图位置 */
const homeRt = reactive({
  times: 0,
  center: {},
  zoom: 12,
});
const initHome = (center, zoom) => {
  homeRt.center = center;
  homeRt.zoom = zoom;
}
watch(() => homeRt.times, (nv, ov) => {
  maps.centerAndZoom(homeRt.center, homeRt.zoom);
});

/* 右侧选中某个单体  */
const unitChange = (item) => {
  openInfoWindow(item);
  maps.centerAndZoom(new window.BMapGL.Point(+item.x, +item.y), 15);
}

const handleCares = (item) => {
  const flag = item.users.includes(info.id);
  if (flag) {
    item.users = item.users.filter(j => j !== info.id);
  } else {
    item.users.push(info.id)
  }
  unitById({
    method: 'patch',
    id: item.id,
    data: {
      users: item.users,
    }
  }).then(res => {
    ElMessage.success(`${ flag ? '取关' : '关注'}成功！`);
  });
}
</script>

<template>
  <div id="map_container" class="BMap_container"></div>
  
  <div class="icons flex-end flex-column">
    <img class="pointer" :src="require('@T2/assets/maps/actions-reset.png')" @click="homeRt.times++"/>
    <img :src="require('@T2/assets/maps/eg-normal.png')" />
    <img :src="require('@T2/assets/maps/eg-alarm.png')" />
    <img :src="require('@T2/assets/maps/eg-offline.png')" />
  </div>
  
  <Units :units="Rt.units" @unit-change="unitChange" v-if="Rt.units" />
  
  <teleport :to="detail.dom" v-if="detail.dom && detail.data">
    <div class="popup flex">
      <div class="line"></div>
      <div class="unit-info flex-center-center flex-column">
        <img
          :src="detail.data.users.includes(info.id) ? require('@T2/assets/common/cares-yes.png') : require('@T2/assets/common/cares-no.png')"
          @click="handleCares(detail.data)"
        />
        <label class="ellipsis">{{ detail.data.name }}{{ detail.data.name }}</label>
        <p>{{ dayjs(detail.data._sensors[1].c[0].timestamp).format('MM-DD HH:mm') }}</p>
      </div>
      <div class="line2"></div>
      <div class="s-box flex-column">
        <div class="s-status flex--center">
          <label>状态：</label>
          <template v-if="detail.data._sensors[0]?.c?.length" v-for="item in (detail.data._sensors[0]?.c[0].c || [])">
            <div class="n-txt ellipsis">{{ item.n }}</div>
            <div class="circle" :class="{ 'warn': item.state, 'offline': item.value === '掉线' }"></div>
          </template>
        </div>
        <div class="s-value flex">
          <template v-if="detail.data._sensors[0]?.c?.length > 1" v-for="item in (detail.data._sensors[0]?.c[1].c || [])">
            <div class="data flex-column" style="width: calc(100%/3);">
              <strong v-if="item.value === '掉线' || !item.value">- -</strong>
              <strong :style="{color: item.state ? '#ff0000' : '#767575'}" v-else>{{ item.value }}({{ item.unit }})</strong>
              <p>{{ item.n }}</p>
            </div>
          </template>
        </div>
      </div>
    </div>
  </teleport>
</template>

<style lang="scss" scoped>
@use '@T2/styles/BMap.scss';
.BMap_container {
  width: 100%;
  height: 100%;
  background-color: rgba(0,0,0,0.5);
}
.icons {
  position: absolute;
  left: 22px;
  bottom: 63px;
  z-index: 100;
  img {
    width: 34px;
    height: 34px;
    margin-top: 13px;
  }
  img:nth-child(1) {
    margin-bottom: 2px;
  }
}
.popup {
  width: 100%;
  height: 100%;
  padding: 12px;
  overflow: hidden;
  position: relative;
  .line,
  .line2 {
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    background-color: #41B7FF;
    width: 3px;
    height: 65px;
  }
  .line2 {
    left: 115px;
    width: 2px;
    background-color: #EBEBFF;
  }
  .unit-info {
    width: 115px;
    height: 100%;
    img {
      width: 15px;
      height: 15px;
      cursor: pointer;
    }
    label {
      font-weight: 500;
      font-size: 14px;
      color: #535253;
      height: 20px;
      line-height: 20px;
      margin-top: 4px;
      width: 93px;
    }
    p {
      width: 93px;
      text-align: left;
      margin-top: 4px;
      font-weight: 400;
      font-size: 12px;
      color: #ABABAB;
      height: 17px;
      line-height: 17px;
    }
  }
  .s-box {
    flex: 1;
    overflow: hidden;
    .s-status {
      font-weight: 400;
      color: #767575;
      label {
        font-size: 12px;
      }
      .n-txt {
        min-width: 40px;
        max-width: 60px;
        text-align: right;
      }
      .circle {
        margin-left: 2px;
        width: 14px;
        height: 14px;
        border-radius: 50%;
        background-color: #00ff00;
        margin-right: 10px;
        &.warn {
          background-color: #ff0000;
        }
        &.offline {
          background-color: #535253;
        }
      }
    }
    .s-value {
      margin-top: 10px;
      color: #767575;
      .data strong {
        font-weight: 500;
        font-size: 12px;
      }
      .data p {
        font-weight: 400;
        font-size: 12px;
      }
    }
  }
}


</style>

<style scoped>
:deep(.BMap_bubble_pop) {
  /* BMap_bubble_top高度为31px,img高度31px，44px为图标高度 */
  transform: translateY(calc(31px + 31px - 44px));
}
:deep(.map-buoy) {
  position: absolute;
  transform: translateX(-50%) translateY(-44px);
  width: 44px;
  height: 44px;
  background: url('@T2/assets/maps/buoy-normal.png') no-repeat center;
  background-size: 100% 100%;
}
:deep(.map-buoy.alarm) {
  background: url('@T2/assets/maps/buoy-alarm.png') no-repeat center;
  background-size: 100% 100%;
}
:deep(.openTips) {
  pointer-events: auto !important;
  overflow: hidden;
  z-index: 1000;
  width: 416px;
  height: 100px;
  background-color: #fff;
  box-shadow: 0px 4px 6px 0px rgba(76,94,111,0.25);
  border-radius: 4px;
}
</style>